
<template>
  <div id="car-eye-player" ref="playsBox" class="plays-box" :class="{'column':type==='column'}">
    <slot></slot>
    <child-play v-for="(item,idx) in screnObjList" :key="item.id" :params="item" :type="type" :style="styleList[idx]" ref="child" :class="{'choice':item.id==currentChoiceId}"  
      @eventListener="eventListener" v-show="!item.hide&&(styleList[idx]&&styleList[idx].display!='none'||!styleList[idx])"></child-play>
    <!--弹出框-->
    <div class="dialog-model allscreen canDrag" v-if="showAlert">
      <div class="dialog-model-content" style="width: 380px;" v-drag>
        <div class="dialog-model-head">
          播放提示({{alertTimeTip+'秒后停止播放'}})
        </div>
        <div class="dialog-model-body">
          <div class="body-info">
            <div class="body-info-attrs" style="padding: 20px 20px 30px 0;box-sizing: border-box;width: 100%;">
              当前已播放超时，是否停止播放以节省流量？
            </div>
            <div class="body-info-btns">
              <el-button class="body-info-btn" type="primary" size="medium" @click="toEmitStop()">停止播放</el-button>
              <el-button class="body-info-btn" type="primary" size="medium" @click="toEmitContinue()">继续播放</el-button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<style lang="scss" scoped>
  .plays-box{
    position: relative;
    width: 100%;
    height: 100%;
    // display: flex;
    // justify-content: space-between;
    // align-items: center;
    // flex-wrap: wrap;
    &.column{
      display: flex;
      flex-wrap: wrap;
      justify-content: flex-start;
      align-content: stretch;
      overflow: hidden;
    }
    .choice{
      outline: 2px solid rgb(30, 144, 255);
    }
  }
</style>
<script>
import childPlay from './childPlay/index.vue';
//$emit-"updateParent" oprateType:1播放单个时触发,2清除单个时触发,3播放失败了,4组件自己触发关闭全部,7录像,8预览该通道对应的车辆的全部通道,9更新播放进度条进度
export default {
  name: "play-jessibuca",
  props:{
    screnObjList:{
      type: Array,
      default:()=>{
        return []
      }
    },
    type: {
      type: String,
      default: "box"//column
    },
    resizeWidth: {
      type: String
    },
    openLimit: {//是否开启5分钟播放时长限制
      type: Boolean,
      default: ()=>{
        return true;
      }
    }
  },
  data() {
    return {
      playItv: null,
      alertTimeTip: this.$store.state.alertTipOfPlayTime,//五分钟弹出提醒框，六分钟不继续就关闭播放
      showAlert: false,
      styleList: [],
      currentChoiceId: null
    }
  },
  components: {
    "child-play": childPlay
  },
  watch: {
    type(val){
      this.setWH();
    },
    "screnObjList.length": {
      handler(newV) {
        this.setWH();
      },
      deep: true
    },
    resizeWidth(val){
      this.setWH();
    }
  },
  beforeDestroy(){
    if(this.playItv){
      clearInterval(this.playItv);
      this.playItv = null;
    }
  },
  mounted(){
    this.setWH();
    if(this.openLimit)this.listenPlayTime();
  },
  methods: {
    setWH(){//设置宽高
      this.styleList = [];
      if(this.type=="box"){
        let widthbfn = 2,heightbfn = 2,total = this.screnObjList.length;
        if(this.screnObjList.length==6)total = 9;
        if(this.screnObjList.length==8)total = 16;
        if(1<Number(Math.sqrt(total)) && Number(Math.sqrt(total))<2){
          widthbfn = 2;
          heightbfn = 1;
        }else{
          widthbfn = Math.sqrt(total);
          heightbfn = Math.sqrt(total);
        }
        for (let i = 0; i < this.screnObjList.length; i++) {
          let temp = {
            width: "calc("+(100/widthbfn)+"% - 2px)",
            height: heightbfn>1?"calc("+(100/heightbfn)+"% - 2px)":"100%",
            float: "left",
            margin: 0,
            display: "block",
            padding: "1px"
          };
          if(i==0&&this.screnObjList.length==6){
            temp.width = "calc("+(100/3*2)+"% - 2px)";
            temp.height = "calc("+(100/3*2)+"% - 3px)";
          }else if(i==0&&this.screnObjList.length==8){
            temp.width = "calc(75% - 2px)";
            temp.height = "calc(75% - 2px)";
          }
          this.styleList.push(temp);
        }
      }else{
        // let node = this.$refs['plays-box'];
        // (node.parentNode.parentNode.offsetWidth||100)*0.33;
        //34是头部slot的高度
        let uselen = 0,useList = [];//已使用窗口数
        for (let i = 0; i < this.screnObjList.length; i++) {
          if(this.screnObjList[i].hadUsed){
            uselen++;
            useList.push(i);
          }
        }
        let h = '100px',wList = [];
        if(uselen<=3){
          h = 'calc(100%/'+uselen+' - '+(34/uselen)+'px)';
          wList.push("100%");
        }else if(uselen<=8){
          h = 'calc(100%/'+Math.ceil(uselen/2)+' - '+(34/Math.ceil(uselen/2))+'px)';
          wList = ["50%","100%"];
        }else{
          h = 'calc(100%/'+Math.ceil(uselen/3)+' - '+(34/Math.ceil(uselen/3))+'px)';
          wList = ["33.333%","50%","100%"];
        }
        for (let i = 0; i < this.screnObjList.length; i++) {
          let w = wList[0],display = "none";
          if(this.screnObjList[i].hadUsed){
            uselen--;
            if(wList.length==3){
              if(useList.length%3==2&&uselen<2){
                w = wList[1];
              }else if(useList.length%3==1&&uselen<1){
                w = wList[2];
              }
            }else if(wList.length==2){
              if(useList.length%2==1&&uselen<1){
                w = wList[1];
              }
            }
            display = "block";
          }
          this.styleList.push({
            width: w,
            height: h,
            margin: 0,
            boxSizing: "border-box",
            display: display,//column模式下用不到的可以隐藏掉以节省空间
            padding: "1px"
          });
        }
      }
    },
    clickScreen(data){
      console.log(data);
      this.currentChoiceId = data.id;
      this.$emit("clickScreen",data);
    },
    specifyPlayVideoH5(index){//指定视频窗口播放-index-第几个窗口，从0开始
      let that = this;
      that.alertTimeTip = that.$store.state.alertTipOfPlayTime;
      let obj = {
        device: that.screnObjList[index].terminalId,
        channel: that.screnObjList[index].channel,
      }
      that.$http.postData("/live/start",obj).then(function(res){
        if(!res.code){
          let playUrl = res.WebSocket;
          if(location.protocol==='https:'){
            playUrl = res.WebSockets;
          }
          that.clickScreen(that.screnObjList[index]);
          that.screnObjList[index].streamid = res.StreamID;
          that.$emit("updateParent",{
            screenId: that.screnObjList[index].id,
            oprateType: 1
          });
          console.log(playUrl);
          that.$refs.child[index].specifyPlayVideoH5(playUrl);
        }
      }).catch(function(err){
        that.$emit("updateParent",{
          screenId: that.screnObjList[index].id,
          oprateType: 2
        });
      });
    },
    sendApiAndreplayVideo(index){//播放器断流太久，重新发送播放请求并且播放
      let that = this;
      if(!!that.screnObjList[index].terminalId&&!!that.screnObjList[index].channel){
        let obj = {
          device: that.screnObjList[index].terminalId,
          channel: that.screnObjList[index].channel,
        }
        console.log("!!!!!!!!!!!!!!!!!!直播!!!!!!播放器断流太久，重新发送播放请求并且播放!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
        that.$http.postData("/live/start",obj).then(function(res){
          if(!res.code){
            that.screnObjList[index].streamid = res.StreamID;
            that.$refs.child[index].sendApiAndreplayVideo();
          }
        }).catch(function(err){
          if(err.code==2){//设备不在线
            that.closePlayH5(index);
          }
        });
      }
    },
    eventListener(data){//监听到播放器事件
      // console.log("监听到播放器事件--------------",data)
      if(data.type=="click"){
        let clickIdx = this.screnObjList.findIndex(_=>_.id===data.id);
        if(clickIdx>-1){
          this.clickScreen(this.screnObjList[clickIdx]);
        }
      }else{
        if(data.realPlay){//直播
          if(data.type=="destroy"&&!!data.terminalId){
            this.destroyPlayH5(this.screnObjList.findIndex(_=>_.id===data.id));
          }else if(data.type=="resendAPI"){
            this.sendApiAndreplayVideo(this.screnObjList.findIndex(_=>_.id===data.id));
          }else{
            let index = this.screnObjList.findIndex(_=>_.id===data.id);
            if(index>-1&&this.screnObjList[index].hadUsed){
              if(data.type=="stop"){
                this.closePlayH5(index);
              }
            }
          }
        }else{//回放
          if(data.type=="timeUpdate"){
            let index = this.screnObjList.findIndex(_=>_.id===data.id);
            let time = data.time;
            if(this.screnObjList[index].isDevice&&!!this.screnObjList[index].offsetTime){
              time = time + parseInt(this.screnObjList[index].offsetTime);
            }
            // console.log("通道时间===="+this.screnObjList[index].channel,time);
            if(time>=this.screnObjList[index].totalTime){
              this.$message({
                message: this.screnObjList[index].name+"CH"+this.screnObjList[index].channel+"播放完成！",
                type: 'success',
                duration: this.$store.state.alertDuration
              });
              this.stopPlaybackVideoH5(index,false,'over');
            }else if(this.screnObjList[index].state==1){
              // console.log("播放器",time);
              this.$emit("updateParent",{
                index: index,
                progress: time,
                oprateType: 9
              });
            }
          }else if(data.type=="record"){
            this.$emit("updateParent",{
              screenId: data.id,
              bool: data.bool,
              oprateType: 7
            });
          }else{
            let index = this.screnObjList.findIndex(_=>_.id===data.id);
            if(index>-1&&this.screnObjList[index].hadUsed){
              this.stopPlaybackVideoH5(index,!!data.needReplay);
            }
          }
        }
      }
    },
    closePlayH5(index){//关闭指定播放
      if(this.screnObjList[index].terminalId&&this.screnObjList[index].channel){
        let that = this;
        that.$refs.child&&that.$refs.child[index]&&that.$refs.child[index].closePlayH5();
        let obj = {
          streamid: that.screnObjList[index].streamid
        }
        that.$http.postData("/live/stop",obj).then(function(res){//暂不支持调用停止接口
          if(!res.code){
          }
        }).catch(function(err){
          console.error("catchcatchcatchcatch",err);
        });
        that.$emit("updateParent",{
          screenId: that.screnObjList[index].id,
          oprateType: 2
        });
      }
    },
    closeAllPlayH5(){//关闭所有视频
      for (let i = 0; i < this.screnObjList.length; i++) {
        if(this.screnObjList[i].hadUsed){
          this.closePlayH5(i);
        }
      }
    },
    destroyPlayH5(index){//子组件销毁时触发
      let that = this;
      if(that.screnObjList[index].terminalId&&that.screnObjList[index].channel){
        let obj = {
          streamid: that.screnObjList[index].streamid
        }
        that.$http.postData("/live/stop",obj).then(function(res){//暂不支持调用停止接口
          if(!res.code){}
        }).catch(function(err){
          console.error("catchcatchcatchcatch",err);
        })
      }
    },
    specifyPlaybackVideoH5(index,url){//指定录像回放1
      this.alertTimeTip = this.$store.state.alertTipOfPlayTime;
      if(!!url){//服务器类型
        this.$emit("updateParent",{
          screenId: this.screnObjList[index].id,
          oprateType: 1
        });
        this.clickScreen(this.screnObjList[index]);
        this.$refs.child[index].specifyPlaybackVideoH5(url);
      }else{//设备类型
        this.specifyPlaybackVideoH5API(index);
      }
    },
    specifyPlaybackVideoH5API(index){//指定录像回放2---设备类型
      let that = this;
      let startTime = new Date(that.screnObjList[index].startTime).getTime();
      if(that.screnObjList[index].progress){//如果播放起始时间不是文件开始时间
        startTime += that.screnObjList[index].progress*1000;
      }
      let params = {
        device: that.screnObjList[index].terminalId,
        channel: that.screnObjList[index].channel,
        starttime: that.formatTime(startTime).replace(" ","T"),
        endtime: that.screnObjList[index].endTime.replace(" ","T")
      }
      that.$http.postData("/vod/start",params).then(function(res){
        if(!res.code&&res){
          let playUrl = res.WebSocket;
          if(location.protocol==='https:'){
            playUrl = res.WebSockets;
          }
          that.screnObjList[index].streamid = res.StreamID;
          that.$emit("updateParent",{
            screenId: that.screnObjList[index].id,
            oprateType: 1
          });
          that.clickScreen(that.screnObjList[index]);
          that.$refs.child[index].specifyPlaybackVideoH5(playUrl);
        }
      }).catch(function(err){
        console.error("catchcatchcatchcatch",err);
        that.$emit("updateParent",{
          screenId: that.screnObjList[index].id,
          oprateType: 3
        });
      });
    },
    pausePlaybackVideoH5(index){//暂停指定录像回放
      this.$refs.child[index].pauseVideoH5();
      if(this.screnObjList[index].isDevice){
        this.playbackCtr(index,'pause');
      }
    },
    recoveryPlaybackVideoH5(index){//由暂停恢复到播放状态
      this.$emit("updateParent",{
        screenId: this.screnObjList[index].id,
        oprateType: 1
      });
      if(this.screnObjList[index].isDevice){
        this.playbackCtr(index,'play');
      }else{
        this.$refs.child[index].recoveryPlayVideoH5();
      }
    },
    stopPlaybackVideoH5(index,needReplay=false,type){//停止指定录像回放,needReplay需要程序直接重新开始回放
      this.$refs.child[index].closePlayH5();
      if(this.screnObjList[index].isDevice){//暂不支持调用停止接口
        this.$http.postData("/vod/stop",{streamid: this.screnObjList[index].streamid}).then(function(res){
          if(!res.code){}
        }).catch(function(err){
          console.error("catchcatchcatchcatch",err);
        });
      }
      this.$emit("updateParent",{
        screenId: this.screnObjList[index].id,
        oprateType: 2,
        needReplay: needReplay,
        isOver: !!type//是否是正常播放完成触发的
      });
    },
    lowPlaybackVideo(index){//慢进播放
      if(this.screnObjList[index].isDevice){
        let that = this;
        that.playbackCtr(index,'scale');
      }
    },
    fastPlaybackVideo(index){//快进播放
      if(this.screnObjList[index].isDevice){
        let that = this;
        that.playbackCtr(index,'scale');
      }
    },
    gragePlaybackVideo(index){//拖动
      if(!this.screnObjList[index].isDevice){//服务器类型
        this.$refs.child[index].gragePlaybackVideo();
      }else{//设备类型
        this.playbackCtr(index,'seek');
      }
    },
    getRatio(index){//获取播放倍数
      let num = 0,rate = 0,type = 0;
      let val = this.screnObjList[index].speed;
      switch(val) {
        case 400:
          num = 4;
          rate = 4;
          type = 1;
          break;
        case 200:
          num = 2;
          rate = 2;
          type = 1;
          break;
        case 100:
          num = 0;
          rate = 1;
          type = 0;
          break;
        case 50:
          num = 2;
          rate = 0.5;
          type = 2;
          break;
        case 25:
          num = 4;
          rate = 0.25;
          type = 2;
          break;
        default:
          break;
      }
      return {api:num,ui:rate,type:type};
    },
    playbackCtr(index,type){//设备类型的回放视频进行控制时需要发送对应的指令
      if(!this.screnObjList[index].hadUsed||!this.screnObjList[index].terminalId)return;//放置松开的时候已经播放改完了
      let that = this;
      let params = {
        streamid: that.screnObjList[index].streamid,
        command: type,
      };
      if(type=='scale'){
        params.scale = that.getRatio(index).ui;//取值0.25、0.5、1、2、4
      }else if(type=='seek'){
        params.range = that.screnObjList[index].progress;//单位秒
      }
      that.$http.postData("/vod/control",params).then(function(res){
        if(!res.code){
          if(type=='play'){
            if(that.screnObjList[index].puaseWaitingTime>=120){//暂停超过两分钟才点击播放的立即重新重头开始播放
              delete that.screnObjList[index].puaseWaitingTime;
              that.stopPlaybackVideoH5(index,true);
            }else{
              that.$refs.child[index].recoveryPlayVideoH5(10,type==0?true:false);
            }
          }else if(type=='pause'){
            that.screnObjList[index].puaseWaitingTime = 1;
          }else{
            if(type=='scale'){
              that.$refs.child[index].speedChangePlay(params.scale);
            }
            if(type=='seek'){
              that.$refs.child[index].clearCacheBufferOfBack();
            }
            setTimeout(function(){
              that.$emit("updateParent",{
                screenId: that.screnObjList[index].id,
                oprateType: 1
              });
            },1000);
          }
        }
      }).catch(function(err){
        console.error("catchcatchcatchcatch",err);
      });
    },
    setVideoVolumeH5(index,num){//设置音量0-1
      this.$refs.child[index].setVideoVolumeH5(num);
    },
    screenshotH5(index){//截图拍照
      this.$refs.child[index].flv_screenshotH5();
    },
    recordVideo(index,type){//录像
      this.$refs.child[index].recordVideo(type);
    },
    listenPlayTime(){//长时间播放自动关闭机制
      if(this.playItv){
        clearInterval(this.playItv);
        this.playItv = null;
      }
      let that = this;
      that.playItv = setInterval(function(){
        if(that.screnObjList.findIndex(_=>_.hadUsed)>-1){
          --that.alertTimeTip;
          if(that.alertTimeTip<=0&&that.showAlert){
            that.showAlert = false;
            that.alertTimeTip = that.$store.state.alertTipOfPlayTime;
            that.$message({
              type:'warning',
              message: "您长时间不操作视频，为节省流量，已为您关闭视频。",
              showClose: true,
              duration: 0
            });
            that.$emit("updateParent",{
              oprateType: 4
            });
          }else if(that.alertTimeTip==60){
            that.showAlert = true;
          }
        }
      },1000);
    },
    toEmitStop(){//停止播放
      this.showAlert = false;
      this.alertTimeTip = this.$store.state.alertTipOfPlayTime;
      this.$emit("updateParent",{
        oprateType: 4
      });
    },
    toEmitContinue(){//继续播放
      this.showAlert = false;
      this.alertTimeTip = this.$store.state.alertTipOfPlayTime;
    }
  }
};
</script>

